﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;
using MemoryDuosControl;

namespace MemoryDuosInterfaz
{
    public partial class AnyadirGalerias : Form
    {
        private List<PictureBox> listaPictureBox;
        private List<String> listaHashesFichero = new List<String>();
        private List<String> listaHashesImagen = new List<String>();
        private List<String> listaRutas = new List<String>();
        private List<Image> listaImagenes = new List<Image>();
        private List<Galería> listaGalerias;
        private bool añadidoDuplicado = false;
        private PictureBox pictureBoxSeleccionado;
        private String nombreAnterior;

        public AnyadirGalerias()
        {
            InitializeComponent();
            inicializarListas();
        }

        public AnyadirGalerias(List<Galería> listaGalerias, List<Image> listaImagenes)
            : this()
        {
            this.listaImagenes = listaImagenes;
            this.listaGalerias = listaGalerias;
            for (int i = 0; i < listaGalerias.Count; i++)
            {
                Galería gal = listaGalerias.ElementAt(i);
                String ruta = Directory.GetCurrentDirectory() + gal.Nombre + gal.Codigo + ObtenerExtension(listaImagenes.ElementAt(0));
                listaImagenes.ElementAt(i).Save(ruta);
                listaHashesImagen.Add(obtenerHash(listaImagenes.ElementAt(i)));
                listaHashesFichero.Add(obtenerHash(ruta));
                listaRutas.Add(ruta);
            }
            refrescarVentana();
            labelNombreGalería.Text = "Editar Galería";
            textBoxNombreGaleria.Text = (from elemento in listaGalerias
                                         group elemento by elemento.Nombre into gr
                                         select gr.Key).ToList().ElementAt(0);
            nombreAnterior = textBoxNombreGaleria.Text;
            ModificarVentanaParaEditar();
        }

        private string ObtenerExtension(Image i)
        {
            if (System.Drawing.Imaging.ImageFormat.Jpeg.Equals(i.RawFormat))
                return ".jpeg";
            else if (System.Drawing.Imaging.ImageFormat.Gif.Equals(i.RawFormat))
                return ".gif";
            else if (System.Drawing.Imaging.ImageFormat.Png.Equals(i.RawFormat))
                return ".png";
            else if (System.Drawing.Imaging.ImageFormat.Icon.Equals(i.RawFormat))
                return ".icon";
            else if (System.Drawing.Imaging.ImageFormat.Bmp.Equals(i.RawFormat))
                return ".bmp";
            return ".jpeg";
        }

        private void ModificarVentanaParaEditar()
        {
            // buttonEliminar1.Hide(); buttonAñadir.Hide();
            buttonCrearGaleria.Hide();
            buttonGuardarCambios.Show();
        }

        private void inicializarListas()
        {
            listaPictureBox = new List<PictureBox> { pictureBox1, pictureBox2, pictureBox3, pictureBox4,pictureBox5,pictureBox6,
                                                    pictureBox7, pictureBox8,pictureBox9,pictureBox10,pictureBox11,pictureBox12
                                                    ,pictureBox13,pictureBox14,pictureBox15,pictureBox16,pictureBox17,pictureBox18
                                                    ,pictureBox19,pictureBox20,pictureBox21};
        }

        private void anyadirImagenes()
        {
            DialogResult result = openFileDialogImagenes.ShowDialog();
            if (result == DialogResult.OK)
            {
                if (openFileDialogImagenes.FileNames.Count() + listaImagenes.Count > 21)
                {
                    MessageBox.Show("Has introducido más de 21 imágenes, escoge una selección de las que más te gusten.",
                        "Información", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    foreach (String ruta in openFileDialogImagenes.FileNames)
                    {
                        Image imagen = Image.FromFile(ruta); //Obtiene la imagen a partir de la ruta del OpenFileDialog
                        String hash = obtenerHash(ruta);
                        String hashImagen = obtenerHash(imagen);
                        if (!listaHashesFichero.Exists(p => p.Equals(hash)) && !listaHashesImagen.Exists(p => p.Equals(hashImagen)))
                        {
                            listaHashesFichero.Add(obtenerHash(ruta));
                            listaHashesImagen.Add(hashImagen);
                            listaImagenes.Add(imagen);
                            listaRutas.Add(ruta);
                        }
                        else añadidoDuplicado = true;
                    }
                }
                if (añadidoDuplicado)
                {
                    MessageBox.Show("Se han detectado imáegenes duplicadas y han sido ignoradas",
                        "Información", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    añadidoDuplicado = false;
                }
            }
            refrescarVentana();
        }

        private void refrescarVentana()
        {
            int i = 0;
            foreach (PictureBox pict in listaPictureBox)
            {
                pict.Image = null;
            }
            foreach (var image in listaImagenes)
            {
                PictureBox pict = listaPictureBox.ElementAt(i); i++;
                pict.Image = image;
            }
        }

        private void eliminarImagen(String nombrePictureBox)
        {
            pictureBoxSeleccionado = null;
            listaImagenes.RemoveAt(obtenerIndex(nombrePictureBox));
            listaHashesFichero.RemoveAt(obtenerIndex(nombrePictureBox));
            listaHashesImagen.RemoveAt(obtenerIndex(nombrePictureBox));
            listaRutas.RemoveAt(obtenerIndex(nombrePictureBox));
            refrescarVentana();
        }

        private string obtenerHash(string ruta)
        {
            using (FileStream stream = File.OpenRead(ruta))
            {
                SHA256Managed sha = new SHA256Managed();
                byte[] hash = sha.ComputeHash(stream);
                return BitConverter.ToString(hash).Replace("-", String.Empty);
            }
        }

        private string obtenerHash(Image img)
        {
            System.Drawing.ImageConverter convertidor =
                       new System.Drawing.ImageConverter();
            byte[] arrBytes = new byte[1];
            arrBytes = (byte[])convertidor.ConvertTo(img, arrBytes.GetType());

            SHA256Managed sha = new SHA256Managed();
            byte[] hash = sha.ComputeHash(arrBytes);
            return BitConverter.ToString(hash).Replace("-", String.Empty);
        }

        private int obtenerIndex(String nombrePictureBox)
        {
            return listaPictureBox.FindIndex(p => p.Name.Equals(nombrePictureBox));
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (listaImagenes.Count < 21)
            {
                anyadirImagenes();
            }
            else
            {
                MessageBox.Show("No se pueden añadir más imágenes", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
        }

        private void buttonEliminar1_Click(object sender, EventArgs e)
        {
            //solo se puede eliminar una imagen si el PictureBox no esta vacio
            if (pictureBoxSeleccionado != null)
            {
                int index = obtenerIndex(pictureBoxSeleccionado.Name);
                if (pictureBoxSeleccionado.Image != null)
                {
                    listaPictureBox.ElementAt(index).BorderStyle = BorderStyle.FixedSingle; //Añadimos de nuevo el borde al PictureBox
                    eliminarImagen(pictureBoxSeleccionado.Name);
                }
                else
                {
                    MessageBox.Show("La imágen seleccionada está en blanco", "Información", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    pictureBoxSeleccionado = null;
                    listaPictureBox.ElementAt(index).BorderStyle = BorderStyle.FixedSingle; //Añadimos de nuevo el borde al PictureBox
                }
            }
            else
            {
                MessageBox.Show("Para eliminar una imágen primero hay que seleccionarla\n Elimina una imágen para poder añadir una nueva",
                    "Información", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void pictureBox_Click(object sender, EventArgs e)
        {
            //Si ha sido seleccionado un PictureBox previamente
            if (pictureBoxSeleccionado != null)
            {
                PictureBox actual = sender as PictureBox;
                int indexActual = obtenerIndex(actual.Name);
                if (pictureBoxSeleccionado.Name.Equals(actual.Name))
                {
                    if (actual.BorderStyle == BorderStyle.None)
                    {
                        listaPictureBox.ElementAt(indexActual).BorderStyle = BorderStyle.FixedSingle; //Añadimos el borde al PictureBox actual
                        pictureBoxSeleccionado = null;
                    }
                    else
                    {
                        listaPictureBox.ElementAt(indexActual).BorderStyle = BorderStyle.None; //Quitamos el borde al PictureBox actual
                        pictureBoxSeleccionado = actual;
                    }
                }
                else
                {
                    int index1 = obtenerIndex(pictureBoxSeleccionado.Name);
                    listaPictureBox.ElementAt(index1).BorderStyle = BorderStyle.FixedSingle; //Añadimos el borde al PictureBox anterior
                    listaPictureBox.ElementAt(indexActual).BorderStyle = BorderStyle.None; //Quitamos el borde al PictureBox actual
                    pictureBoxSeleccionado = actual;
                }
            }
            else
            {
                //Almacena el nombre del PictureBox seleccionado para posteriormente poder ser eliminado
                pictureBoxSeleccionado = sender as PictureBox;
                int index = obtenerIndex(pictureBoxSeleccionado.Name);
                listaPictureBox.ElementAt(index).BorderStyle = BorderStyle.None; //Quitamos el borde al PictureBox para que el usuario sepa cual ha seleccionado
            }
        }

        private void buttonCrearGaleria_Click(object sender, EventArgs e)
        {
            if (listaImagenes.Count < 21 || listaRutas.Count < 21)
            {
                MessageBox.Show("Para poder crear una galería tienes que subir 21 imágenes", "Información", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (textBoxNombreGaleria.Text.Equals(""))
            {
                MessageBox.Show("Debes introducir un nombre para la galería", "Información", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            //Subir Galería
            SubirImagenes(textBoxNombreGaleria.Text);
        }

        private void SubirImagenes(String nombre)
        {
            foreach (var ruta in listaRutas)
            {
                AccesoGaleria.Subir(nombre, ruta);
                progressBar3.PerformStep();
            }
        }

        private void buttonGuardarCambios_Click(object sender, EventArgs e)
        {
            EstadoPeticion estado = AccesoGaleria.EliminarGalería(nombreAnterior);
            if (estado.Estado == true)
            {
                SubirImagenes(textBoxNombreGaleria.Text);

                MessageBox.Show("Galería subida Correctamente");
                this.Close();
            }
            else MessageBox.Show(estado.Error);
        }

        private string ObtenerNombreGaleríaLista()
        {
            return (from elemento in listaGalerias
                    group elemento by elemento.Nombre into gr
                    select gr.Key).ToList().ElementAt(0);
        }

        private void buttonModificarImagen_Click(object sender, EventArgs e)
        {
            if (pictureBoxSeleccionado != null)
            {
                var resultado = openFileDialogImagen.ShowDialog();
            }
        }
    }
}
